<?php
/**
 * 
 * 回调基础类
 * @author widyhu
 *
 */
use think\Db;
use app\api\controller\Goeasy;
use app\api\controller\Send;
class WxPayNotify extends WxPayNotifyReply
{
	private $config = null;
	/**
	 * 
	 * 回调入口
	 * @param bool $needSign  是否需要签名返回
	 */
	final public function Handle($config, $needSign = true)
	{
		$this->config = $config;
		$msg = "OK";
		//当返回false的时候，表示notify中调用NotifyCallBack回调失败获取签名校验失败，此时直接回复失败
		$result = WxpayApi::notify($config, array($this, 'NotifyCallBack'), $msg);
		if($result == false){
			$this->SetReturn_code("FAIL");
			$this->SetReturn_msg($msg);
			$this->ReplyNotify(false);
			return;
		} else {
			//该分支在成功回调到NotifyCallBack方法，处理完成之后流程
			$this->SetReturn_code("SUCCESS");
			$this->SetReturn_msg("OK");
		}
		$this->ReplyNotify($needSign);
	}
	
	/**
	 * 
	 * 回调方法入口，子类可重写该方法
	 	//TODO 1、进行参数校验
		//TODO 2、进行签名验证
		//TODO 3、处理业务逻辑
	 * 注意：
	 * 1、微信回调超时时间为2s，建议用户使用异步处理流程，确认成功之后立刻回复微信服务器
	 * 2、微信服务器在调用失败或者接到回包为非确认包的时候，会发起重试，需确保你的回调是可以重入
	 * @param WxPayNotifyResults $objData 回调解释出的参数
	 * @param WxPayConfigInterface $config
	 * @param string $msg 如果回调处理失败，可以将错误信息输出到该方法
	 * @return true回调出来完成不需要继续回调，false回调处理未完成需要继续回调
	 */
	public function NotifyProcess($objData, $config, &$msg)
	{
		//TODO 用户基础该类之后需要重写该方法，成功的时候返回true，失败返回false
		$data = $objData->GetValues();
		error_log(json_encode($data),3,'vxpay1.log');
		if(!array_key_exists("return_code", $data) 
			||(array_key_exists("return_code", $data) && $data['return_code'] != "SUCCESS")) {
			//TODO失败,不是支付成功的通知
			//如果有需要可以做失败时候的一些清理处理，并且做一些监控
			$msg = "异常异常";
			return false;
		}
		if(!array_key_exists("transaction_id", $data)){
			$msg = "输入参数不正确";
			return false;
		}
		error_log('out_trade_no------------'.$data['out_trade_no'],3,'vxpay1.log');
		
		
		$checkResult = $objData->CheckSign($config);
		if($checkResult == false){
			//签名错误
			error_log('签名错误！',3,'vxpay1.log');
		}
		$out_trade_no = substr($data['out_trade_no'],5);
		$type = '微信';
		if($out_trade_no[0] == "I"){
		    //商城订单
		    $reorder = Db::name('reorder')->where('order_sn',$out_trade_no)->find();
		    if($reorder['status'] != 1){
    		    echo 'success';die;
    		}
            $user = Db::name('personal')->where('id',$reorder['buyid'])->value('switch');
		    if ($user == 2) {
                $ret1 = [
                    'uid'   =>  $reorder['buyid'],
                    'log_sn'    =>  date('YmdHis') . rand(10000000,99999999),
                    'money' =>  '-'.$reorder['prices'],
                    'type'  =>  1,
                    'content'   =>  '收货订单交易',
                    'createtime'    =>  time(),
                    'arrivaltime'   =>  time(),
                    'status'    =>  1
                ];
                $re['s1'] = Db::name('reorder')->where('order_sn',$out_trade_no)->update(['status'=>30,'paytime'=>time(),'payway'=>$type]);
                $re['s2'] = Db::name('account_log')->insert($ret1);
            } else {
                $ret1 = [
                    'uid'   =>  $reorder['buyid'],
                    'log_sn'    =>  date('YmdHis') . rand(10000000,99999999),
                    'money' =>  '-'.$reorder['prices'],
                    'type'  =>  1,
                    'content'   =>  '收货订单交易',
                    'createtime'    =>  time(),
                    'arrivaltime'   =>  time(),
                    'status'    =>  1
                ];
                $re['s1'] = Db::name('reorder')->where('order_sn',$out_trade_no)->update(['status'=>2,'paytime'=>time(),'payway'=>$type]);
                $re['s2'] = Db::name('account_log')->insert($ret1);
                $send = new Send();
                if ($reorder['order_user'] == 1) {
                    $goods = Db::name('receiving')->where('id',$reorder['goods_id'])->find();
                    $re['s3'] = $send->send($goods['mobile'],6);
                } else {
                    $goods = Db::name('personal')->where('id',$reorder['uid'])->find();
                    $re['s4'] = $send->send($goods['mobile'],9);
                }
            }
		    
		}else{
		    $order = db::name('order')->where('order_sn',$out_trade_no)->find();
		
    		if($order['status'] != 1){
    		    echo 'success';die;
    		}
            $auth_group = DB::name("auth_group")->where(['name'=>['in',['投诉咨询','一级客服']]])->column('id');
            $auth_group_access = DB::name("auth_group_access")->where(['group_id'=>['in',$auth_group]])->column("uid");
            $admin_id = Db::name('admin')->where(['status'=>'normal','id'=>['in',$auth_group_access]])->orderRaw('Rand()')->value('id');
    		error_log('order info-----------'.json_encode($order),3,'vxpay1.log');
    		$goods = Db::name('goods')->where('id',$order['goods_id'])->find();


            $user = Db::name('personal')->where('id',$order['buyid'])->value('switch');
            if ($user == 2) {
                $ret1 = [
                    'uid'   =>  $order['buyid'],
                    'log_sn'    =>  date('YmdHis') . rand(10000000,99999999),
                    'money' =>  '-'.$order['amount'],
                    'type'  =>  1,
                    'content'   =>  '消费',
                    'createtime'    =>  time(),
                    'arrivaltime'   =>  time(),
                    'status'    =>  1
                ];
                $re['s1'] = Db::name('order')->where('order_sn',$out_trade_no)->update(['status'=>30,'paytime'=>time(),'payway'=>$type]);
                $re['s2'] = Db::name('account_log')->insert($ret1);
            } else {
                if ($goods['goods_class_type'] == 1) {
                    error_log("账号交易",3,'vxpay1.log');
                    $ret1 = [
                        'uid'   =>  $order['buyid'],
                        'log_sn'    =>  date('YmdHis') . rand(10000000,99999999),
                        'money' =>  '-'.$order['amount'],
                        'type'  =>  1,
                        'content'   =>  '消费',
                        'createtime'    =>  time(),
                        'arrivaltime'   =>  time(),
                        'status'    =>  1
                    ];
                    $re['s1'] = Db::name('order')->where('order_sn',$out_trade_no)->update(['status'=>11,'paytime'=>time(),'payway'=>$type]);
                    $re['s2'] = Db::name('account_log')->insert($ret1);
                    $easy = new Goeasy();
                    $msg = '您有待验证的订单了!';
                    $re['s5'] = $easy->sendToAdmin($admin_id,$msg);
                } else {
                    error_log("金币交易",3,'vxpay1.log');
                    $ret1 = [
                        'uid'   =>  $order['buyid'],
                        'log_sn'    =>  date('YmdHis') . rand(10000000,99999999),
                        'money' =>  '-'.$order['amount'],
                        'type'  =>  1,
                        'content'   =>  '消费',
                        'createtime'    =>  time(),
                        'arrivaltime'   =>  time(),
                        'status'    =>  1
                    ];
                    //                $re['s1'] = Db::name('order')->where('order_sn',$out_trade_no)->update(['status'=>2,'paytime'=>time(),'payway'=>$type]);
                    if ($goods['method'] == 3) {
                        $re['s1'] = Db::name('order')->where('order_sn',$out_trade_no)->update(['status'=>5,'paytime'=>time(),'payway'=>$type]);
                    } else {
                        $re['s1'] = Db::name('order')->where('order_sn',$out_trade_no)->update(['status'=>2,'paytime'=>time(),'payway'=>$type]);
                    }
                    $re['s2'] = Db::name('account_log')->insert($ret1);
                    $send = new Send();
                    $re['s3'] = $send->send($goods['mobile'],2);
                    $easy = new Goeasy();
                    $msg = '您有待发货的订单了!';
                    $re['s5'] = $easy->sendToAdmin($admin_id,$msg);
                }
            }

            error_log("交易11完成",3,'vxpay1.log');
		    return false;
		}
		
	}

	/**
	*
	* 业务可以继承该方法，打印XML方便定位.
	* @param string $xmlData 返回的xml参数
	*
	**/
	public function LogAfterProcess($xmlData)
	{
		return;
	}
	
	/**
	 * 
	 * notify回调方法，该方法中需要赋值需要输出的参数,不可重写
	 * @param array $data
	 * @return true回调出来完成不需要继续回调，false回调处理未完成需要继续回调
	 */
	final public function NotifyCallBack($data)
	{
		$msg = "OK";
		$result = $this->NotifyProcess($data, $this->config, $msg);
		
		if($result == true){
			$this->SetReturn_code("SUCCESS");
			$this->SetReturn_msg("OK");
		} else {
			$this->SetReturn_code("FAIL");
			$this->SetReturn_msg($msg);
		}
		return $result;
	}
	
	/**
	 * 
	 * 回复通知
	 * @param bool $needSign 是否需要签名输出
	 */
	final private function ReplyNotify($needSign = true)
	{
		//如果需要签名
		if($needSign == true && 
			$this->GetReturn_code() == "SUCCESS")
		{
			$this->SetSign($this->config);
		}

		$xml = $this->ToXml();
		$this->LogAfterProcess($xml);
		WxpayApi::replyNotify($xml);
	}
}